home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / comm / amigatcp.1 next >
Text File  |  1989-03-18  |  64KB  |  2,466 lines

  1. Path: xanth!ukma!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i080:  amigatcp - tcp/ip for the amiga, Part01/06
  5. Message-ID: <12328@swan.ulowell.edu>
  6. Date: 17 Mar 89 23:15:36 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2455
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: rminnich@super.org (Ronald G. Minnich)
  12. Posting-number: Volume 89, Issue 80
  13. Archive-name: comm/amigatcp.1
  14.  
  15. [Here is a freely redistributable TCP/IP package for the Amiga, also
  16. known as the KA9Q package.  Executables and documentation are in
  17. comp.binaries.amiga.  To my knowledge, this is the same package that
  18. has been available for some time.  ..Bob]
  19.  
  20. #    This is a shell archive.
  21. #    Remove everything above and including the cut line.
  22. #    Then run the rest of the file through sh.
  23. #----cut here-----cut here-----cut here-----cut here----#
  24. #!/bin/sh
  25. # shar:    Shell Archiver
  26. #    Run the following text with /bin/sh to create:
  27. #    amiga.h
  28. #    arp.h
  29. #    ax25.h
  30. #    cmdparse.h
  31. #    ether.h
  32. #    ftp.h
  33. #    functions.h
  34. #    icmp.h
  35. #    iface.h
  36. #    inetdev.h
  37. #    inetlib.h
  38. #    internet.h
  39. #    ip.h
  40. #    machdep.h
  41. #    mbuf.h
  42. #    netrom.h
  43. #    netuser.h
  44. #    session.h
  45. #    slip.h
  46. #    smtp.h
  47. #    tcp.h
  48. #    telnet.h
  49. #    timer.h
  50. #    trace.h
  51. #    udp.h
  52. #    cmdparse.c
  53. #    ether.c
  54. #    ftp.c
  55. #    hexload.c
  56. #    makefile
  57. #    misc.c
  58. #    netrom.c
  59. #    netuser.c
  60. #    smisc.c
  61. #    tcptimer.c
  62. #    timer.c
  63. #    tnserv.c
  64. #    ttydriv.c
  65. # This archive created: Fri Mar 17 17:56:19 1989
  66. cat << \SHAR_EOF > amiga.h
  67. #define    ASY_MAX    1    /* one serial port on an amiga */
  68.  
  69. struct asy {
  70.     unsigned char  *input_buffer;    /* point to input buffer */
  71.     unsigned    buflen;        /* length of recv buffer */
  72.     unsigned char  *input_p;    /* pointer to current byte */
  73.     unsigned    input_len;    /* bytes left */
  74.     unsigned    speed;        /* line speed */
  75.     unsigned    addr;        /* address: we'll use this as unit number */
  76.     unsigned    vec;        /* vector: right. */
  77. };
  78.  
  79. extern struct asy asy[ASY_MAX];
  80. extern unsigned nasy;
  81. SHAR_EOF
  82. cat << \SHAR_EOF > arp.h
  83. /* Size of ARP hash table */
  84. #define    ARPSIZE    17
  85.  
  86. /* Lifetime of a valid ARP entry (seconds) */
  87. #define    ARPLIFE        (15*60)    /* 15 minutes */
  88. /* Lifetime of a pending ARP entry (seconds) */
  89. #define    PENDTIME    15    /* 15 seconds */
  90.  
  91. /* ARP definitions (see RFC 826) */
  92.  
  93. /* Address size definitions */
  94. #define    IPALEN    4        /* Length in bytes of an IP address */
  95. #define    MAXHWALEN    255    /* Maximum length of a hardware address */
  96.  
  97. /* ARP opcodes */
  98. #define    ARP_REQUEST    1
  99. #define    ARP_REPLY    2
  100.  
  101. /* Hardware types */
  102. #define    ARP_ETHER    1    /* Assigned to 10 megabit Ethernet */
  103. #define    ARP_EETHER    2    /* Assigned to experimental Ethernet */
  104. #define    ARP_AX25    3    /* Assigned to AX.25 Level 2 */
  105. #define    ARP_PRONET    4    /* Assigned to PROnet token ring */
  106. #define    ARP_CHAOS    5    /* Assigned to Chaosnet */
  107. #define    ARP_ARCNET    7
  108.  
  109. /* Table of hardware types known to ARP */
  110. struct arp_type {
  111.     int hwalen;        /* Hardware length */
  112.     int iptype;        /* Hardware type field for IP */
  113.     int arptype;        /* Hardware type field for ARP */
  114.     char *bdcst;        /* Hardware broadcast address */
  115.     int (*format)();    /* Function that formats addresses */
  116.     int (*scan)();        /* Reverse of format */
  117. };
  118. extern struct arp_type arp_type[];
  119.  
  120. /* Format of an ARP request or reply packet. From p. 3 */
  121. struct arp {
  122.     int16 hardware;            /* Hardware type */
  123.     int16 protocol;            /* Protocol type */
  124.     unsigned char hwalen;        /* Hardware address length, bytes */
  125.     unsigned char pralen;        /* Length of protocol address */
  126.     int16 opcode;            /* ARP opcode (request/reply) */
  127.     char shwaddr[MAXHWALEN];    /* Sender hardware address field */
  128.     int32 sprotaddr;        /* Sender Protocol address field */
  129.     char thwaddr[MAXHWALEN];    /* Target hardware address field */
  130.     int32 tprotaddr;        /* Target protocol address field */
  131. };
  132.         
  133. /* Format of ARP table */
  134. struct arp_tab {
  135.     struct arp_tab *next;    /* Doubly-linked list pointers */
  136.     struct arp_tab *prev;    
  137.     int32 ip_addr;        /* IP Address, host order */
  138.     int16 hardware;        /* Hardware type */
  139.     char *hw_addr;        /* Hardware address */
  140.     char state;        /* (In)complete */
  141. #define    ARP_PENDING    0
  142. #define    ARP_VALID    1
  143.     struct timer timer;    /* Time until aging this entry */
  144.     struct mbuf *pending;    /* Queue of datagrams awaiting resolution */
  145. };
  146. #define    NULLARP    (struct arp_tab *)NULL
  147. extern struct arp_tab *arp_tab[];
  148.  
  149. struct arp_stat {
  150.     int recv;    /* Total number of ARP packets received */
  151.     int badtype;    /* Incoming requests for unsupported hardware */
  152.     int badlen;    /* Incoming length field(s) didn't match types */
  153.     int inreq;    /* Incoming requests for us */
  154.     int replies;    /* Replies sent */
  155.     int outreq;    /* Outoging requests sent */
  156. };
  157. SHAR_EOF
  158. cat << \SHAR_EOF > ax25.h
  159. /* Control field templates */
  160. #define    I    0x00    /* Information frames */
  161. #define    S    0x01    /* Supervisory frames */
  162. #define    RR    0x01    /* Receiver ready */
  163. #define    RNR    0x05    /* Receiver not ready */
  164. #define    REJ    0x09    /* Reject */
  165. #define    U    0x03    /* Unnumbered frames */
  166. #define    SABM    0x2f    /* Set Asynchronous Balanced Mode */
  167. #define    DISC    0x43    /* Disconnect */
  168. #define    DM    0x0f    /* Disconnected mode */
  169. #define    UA    0x63    /* Unnumbered acknowledge */
  170. #define    FRMR    0x87    /* Frame reject */
  171. #define    UI    0x03    /* Unnumbered information */
  172. #define    PF    0x10    /* Poll/final bit */
  173.  
  174. /* FRMR reason bits */
  175. #define    W    1    /* Invalid control field */
  176. #define    X    2    /* Unallowed I-field */
  177. #define    Y    4    /* Too-long I-field */
  178. #define    Z    8    /* Invalid sequence number */
  179.  
  180. /* Format of an AX.25 address - left-shifted callsign plus sub station ID */
  181. #define    ALEN    6    /* Number of chars in callsign field */
  182. struct ax25_addr {
  183.     char call[ALEN];    
  184.     char ssid;
  185. };
  186. /*
  187.  *  It seems that some compilers (on VAX and 68K hardware) round up 
  188.  *  structure sizes to quad- or double-byte boundaries.  Hmm..
  189.  */
  190. /* AX.25 address length (7 bytes) */
  191. #define    AXALEN        (ALEN+1)    /* (sizeof(struct ax25_addr)) */
  192.  
  193. /* SSID address byte definitions */
  194. #define    SSID        0x1e    /* Sub station ID */
  195. #define    REPEATED    0x80    /* Has-been-repeated bit in repeater field */
  196. #define    E        0x01    /* Address extension bit */
  197. #define    C        0x80    /* Command/response designation */
  198.  
  199. #define    UNKNOWN        0
  200. #define    COMMAND        1
  201. #define    RESPONSE    2
  202.  
  203. #define    PID_ARP        0xcd    /* AX.25 Level 3 PID for ARP */
  204. #define    PID_IP        0xcc    /* AX.25 Level 3 PID for IP */
  205. #define PID_NETROM    0xcf    /* AX.25 Level 3 PID for NET/ROM frames */
  206.  
  207. /* Our AX.25 address */
  208. extern struct ax25_addr mycall;
  209.  
  210. /* AX.25 broadcast address: "QST   -0" in shifted ASCII */
  211. extern struct ax25_addr ax25_bdcst;
  212. SHAR_EOF
  213. cat << \SHAR_EOF > cmdparse.h
  214. #define    NARG        10    /* Max number of args to commands */
  215.  
  216. struct cmds {
  217.     char *name;        /* Name of command */
  218.     int (*func)();        /* Function to execute command */
  219.         int  argcmin;        /* Minimum number of args */
  220.         char *argc_errmsg;    /* Message to print if insufficient args */
  221.         char *exec_errmsg;    /* Message to print if function fails */
  222. };
  223. #ifndef    NULLCHAR
  224. #define    NULLCHAR    (char *)0
  225. #endif
  226. SHAR_EOF
  227. cat << \SHAR_EOF > ether.h
  228. /* Generic Ethernet constants and templates */
  229.  
  230. #define    EADDR_LEN    6
  231. /* Format of an Ethernet header */
  232. struct ether {
  233.     char dest[EADDR_LEN];
  234.     char source[EADDR_LEN];
  235.     int16 type;
  236. };
  237. /* Ethernet broadcast address */
  238. extern char ether_bdcst[];
  239.  
  240. /* Ethernet type fields */
  241. #define    IP_TYPE        0x800    /* Type field for IP */
  242. #define    ARP_TYPE    0x806    /* Type field for ARP */
  243.  
  244. #define    HDR        sizeof(struct ether)    /* Size of Ethernet header */
  245.  
  246. #define    RUNT        60    /* smallest legal size packet, no fcs */
  247. #define    GIANT        1514    /* largest legal size packet, no fcs */
  248. SHAR_EOF
  249. cat << \SHAR_EOF > ftp.h
  250. #define    FTP_PORT    21    /* Control port */
  251. #define    FTPD_PORT    20    /* Data port */
  252. #define CTLZ    26        /* EOF for CP/M systems */
  253.  
  254. /* Per-session control block */
  255. struct ftp {
  256.     struct ftp *prev;    /* Linked list pointers */
  257.     struct ftp *next;
  258.     struct tcb *control;    /* TCP control connection */
  259.     char state;
  260. #define    COMMAND_STATE    0    /* Awaiting user command */
  261. #define    SENDING_STATE    1    /* Sending data to user */
  262. #define    RECEIVING_STATE    2    /* Storing data from user */
  263.  
  264.     char type;        /* Transfer type */
  265. #define    IMAGE_TYPE    0
  266. #define    ASCII_TYPE    1
  267.  
  268.     FILE *fp;        /* File descriptor being transferred */
  269.     struct socket port;    /* Remote port for data connection */
  270.     struct tcb *data;    /* Data connection */
  271.  
  272.     /* The following are used only by the server */
  273.     char *username;        /* User's name */
  274.     char *buf;        /* Input command buffer */
  275.     char cnt;        /* Length of input buffer */
  276. #ifdef    AMIGA
  277.     unsigned long cd;    /* lock on current directory *.
  278. #else
  279.     char *cd;        /* Current directory name */
  280. #endif
  281.     /* And this is used only by the client */
  282.     struct session *session;
  283. };
  284.  
  285. #define    NULLFTP    (struct ftp *)NULL
  286. SHAR_EOF
  287. cat << \SHAR_EOF > functions.h
  288. #define LATTICE    1
  289. SHAR_EOF
  290. cat << \SHAR_EOF > icmp.h
  291. /* Internet Control Message Protocol */
  292.  
  293. /* Message types */
  294. #define    ECHO_REPLY    0    /* Echo Reply */
  295. #define    DEST_UNREACH    3    /* Destination Unreachable */
  296. #define    QUENCH        4    /* Source Quench */
  297. #define    REDIRECT    5    /* Redirect */
  298. #define    ECHO        8    /* Echo Request */
  299. #define    TIME_EXCEED    11    /* Time-to-live Exceeded */
  300. #define    PARAM_PROB    12    /* Parameter Problem */
  301. #define    TIMESTAMP    13    /* Timestamp */
  302. #define    TIME_REPLY    14    /* Timestamp Reply */
  303. #define    INFO_RQST    15    /* Information Request */
  304. #define    INFO_REPLY    16    /* Information Reply */
  305.  
  306. struct icmp {
  307.     char type;
  308.     char code;
  309.     int16 checksum;
  310.     union icmp_args {
  311.         int32 unused;
  312.         char pointer;
  313.         int32 address;
  314.         struct {
  315.             int16 id;
  316.             int16 seq;
  317.         } echo;
  318.     } args;
  319. };
  320. #define    NULLICMP    ((union icmp_args *)NULL)
  321.     
  322. /* Destination Unreachable codes */
  323. #define    NET_UNREACH    0    /* Net unreachable */
  324. #define    HOST_UNREACH    1    /* Host unreachable */
  325. #define    PROT_UNREACH    2    /* Protocol unreachable */
  326. #define    PORT_UNREACH    3    /* Port unreachable */
  327. #define    FRAG_NEEDED    4    /* Fragmentation needed and DF set */
  328. #define    ROUTE_FAIL    5    /* Source route failed */
  329.  
  330. /* Time Exceeded codes */
  331. #define    TTL_EXCEED    0    /* Time-to-live exceeded */
  332. #define    FRAG_EXCEED    1    /* Fragment reassembly time exceeded */
  333.  
  334. /* Redirect message codes */
  335. #define    REDR_NET    0    /* Redirect for the network */
  336. #define    REDR_HOST    1    /* Redirect for the host */
  337. #define    REDR_TOS    2    /* Redirect for Type of Service, or-ed with prev */
  338.  
  339. struct icmp_errors {
  340.     unsigned checksum;        /* ICMP Checksum errors */
  341.     unsigned nospace;        /* alloc_mbuf failed someplace */
  342.     unsigned noloop;        /* No ICMP in response to an ICMP */
  343.     unsigned bdcsts;        /* Ignore broadcast ICMPs */
  344. };
  345. #define    ICMP_TYPES    17
  346. struct icmp_stats {
  347.     unsigned input[ICMP_TYPES];    /* ICMP input stats by type */
  348.     unsigned output[ICMP_TYPES];    /* ICMP output stats by type */
  349. };
  350.  
  351. void icmp_dump();
  352. SHAR_EOF
  353. cat << \SHAR_EOF > iface.h
  354. /* Interface control structure */
  355. struct interface {
  356.     struct interface *next;    /* Linked list pointer */
  357.     char *name;        /* Ascii string with interface name */
  358.     int16 mtu;        /* Maximum transmission unit size */
  359.     int (*send)();        /* Routine to call to send IP datagram */
  360.     int (*output)();    /* Routine to call to send raw packet */
  361.     int (*recv)();        /* Routine to kick to process input */
  362.     int (*stop)();        /* Routine to call before detaching */
  363.     int16 dev;        /* Subdevice number to pass to send */
  364.     int16 flags;        /* State of interface */
  365. #define    IF_ACTIVE    0x01
  366. #define    IF_BROADCAST    0x04    /* Interface is capable of broadcasting */
  367.     char *hwaddr;        /* Device hardware address, if any */
  368. };
  369. #define    NULLIF    (struct interface *)NULL
  370. extern struct interface *ifaces;    /* Head of interface list */
  371. SHAR_EOF
  372. cat << \SHAR_EOF > inetdev.h
  373. /*
  374.  *  Copyright (C) 1987
  375.  *  Louis A. Mamakos  WA3YMH
  376.  *  All rights reserved.
  377.  *
  378.  *  This code may not be redistributed, sold, included on any collection of
  379.  *  software which is sold.  Use of this software is restricted to inclusion
  380.  *  in the KA9Q TCP/IP software package for use on a Commodore-Amiga system.
  381.  *  Commercial use is prohibited.  Only educational and Amateur Packet Radio
  382.  *  use is allowed.
  383.  */
  384.  
  385. #ifndef    EXEC_SEMAPHORES_H
  386. #include <exec/semaphores.h>
  387. #endif
  388.  
  389.  
  390. struct InternetBase {
  391.     struct Library lib;
  392.  
  393.     /* use AttemptSemaphore()/ObtainSemaphore()/ReleaseSemaphore() */
  394.     struct SignalSemaphore ib_lock;
  395.  
  396.     /* add any user visible variables here */
  397.     struct List    ib_Units;
  398. } *InternetBase;
  399.  
  400.  
  401. struct IOINETReq {
  402.     struct    Message    io_Message;
  403.     struct    Device    *io_Device;    /* device node pointer */
  404.     struct INET_Unit    *io_Unit;        /* unit (driver private) */
  405.     UWORD    io_Command;        /* device command */
  406.     UBYTE    io_Flags;
  407.     BYTE    io_Error;
  408.     ULONG    io_Actual;
  409.     ULONG    io_Length;
  410.     APTR    io_Data;
  411.     ULONG    io_Offset;
  412.     union {
  413.         struct TCP_state_u {
  414.             UBYTE    io_u_OldState;    /* old TCP state */
  415.             UBYTE    io_u_State;    /* new tcp state */
  416.         } io_TCP_State_u;
  417.         /* add more members of union here (protocol specific) */
  418.     } io_INET_u;
  419.     struct    socket io_lsocket;    /* local socket address */
  420.     struct    socket io_fsocket;    /* remote socket address */
  421.  
  422. /* parameters used on OpenDevice() only */
  423. #define    io_TCP_Window    io_Length
  424. #define    io_INET_TOS    io_Actual
  425.  
  426. /* define easier to use names for members of protocol specific status union */
  427. #define    io_OldState    io_INET_u.io_TCP_State_u.io_u_OldState
  428. #define io_State    io_INET_u.io_TCP_State_u.io_u_State
  429.  
  430. };
  431.  
  432.  
  433. struct INET_Unit {
  434.     struct    Node iu_Unit;        /* list thread */
  435.     struct    List iu_Input;        /* queue of read requests */
  436.     struct    List iu_Output;        /* queue of write reqeusts */
  437.     struct    IOINETReq *iu_Act_Input;/* current active input request */
  438.     struct    IOINETReq *iu_Act_Output;/* current active output request */
  439.     void    *iu_ccb;        /* generic control block 
  440.                        (TCP/UDP protocol specific) */
  441.     ULONG    iu_user;        /* user supplied "cookie" */
  442.     ULONG    iu_type;        /* type of connection (UDP/TCP..) */
  443. };
  444.  
  445. #define IN_VERSION    1
  446. #define IN_REVISION    0
  447.  
  448. #define INET_UNIT_RAW    0L
  449. #define    INET_UNIT_TCP    1L
  450. #define    INET_UNIT_UDP    2L
  451. SHAR_EOF
  452. cat << \SHAR_EOF > inetlib.h
  453. #pragma libcall  InternetBase DSOpen 1e 109e04
  454. #pragma libcall  InternetBase DSClose 24 9e02
  455. #pragma libcall  InternetBase DSExpunge 2a e01
  456. #pragma libcall  InternetBase DSBeginIO 30 e902
  457. #pragma libcall  InternetBase DSAbortIO 36 e902
  458. SHAR_EOF
  459. cat << \SHAR_EOF > internet.h
  460. /* Global structures and constants pertaining to the interface between IP and
  461.  *     higher level protocols
  462.  */
  463.  
  464. /* IP protocol field values */
  465. #define    ICMP_PTCL    1    /* Internet Control Message Protocol */
  466. #define    TCP_PTCL    6    /* Transmission Control Protocol */
  467. #define    UDP_PTCL    17    /* User Datagram Protocol */
  468.  
  469. #define    MAXTTL        255    /* Maximum possible IP time-to-live value */
  470.  
  471. /* DoD-style precedences */
  472. #define    ROUTINE        0x00
  473. #define    PRIORITY    0x20
  474. #define    IMMEDIATE    0x40
  475. #define    FLASH        0x60
  476. #define    FLASH_OVER    0x80
  477. #define    CRITIC        0xa0
  478. #define    INET_CTL    0xc0
  479. #define    NET_CTL        0xe0
  480.  
  481. /* Amateur-style precedences */
  482. #define    AM_ROUTINE    0x00
  483. #define    AM_WELFARE    0x20
  484. #define    AM_PRIORITY    0x40
  485. #define    AM_EMERGENCY    0x60
  486.  
  487. /* Class-of-service bits */
  488. #define    LOW_DELAY    0x10
  489. #define    THROUGHPUT    0x08
  490. #define    RELIABILITY    0x04
  491.  
  492. /* IP TOS fields */
  493. #define    PREC(x)        ((x)>>5 & 7)
  494. #define    DELAY        0x10
  495. #define    THRUPUT        0x8
  496. #define    RELIABLITY    0x4
  497.  
  498. /* Pseudo-header for TCP and UDP checksumming */
  499. struct pseudo_header {
  500.     int32 source;        /* IP source */
  501.     int32 dest;        /* IP destination */
  502.     char zero;
  503.     char protocol;        /* Protocol */
  504.     int16 length;        /* Data field length */
  505. };
  506. #define    NULLHEADER    (struct pseudo_header *)NULL
  507. void tcp_input(),udp_input(),ip_send(),dump_ip();
  508. SHAR_EOF
  509. cat << \SHAR_EOF > ip.h
  510. #define    NROUTE    5    /* Number of hash chains in routing table */
  511.  
  512. extern int32 ip_addr;    /* Our IP address for ICMP and source routing */
  513.  
  514. extern char ip_ttl;    /* Default time-to-live for IP datagrams */
  515.  
  516. struct ip_header {
  517.     char v_ihl;        /* Version + IP header length */
  518. #define    IPVERSION    4
  519.     char tos;        /* Type of service */
  520.     int16 length;        /* Total length */
  521.     int16 id;        /* Identification */
  522.     int16 fl_offs;        /* Flags + fragment offset */
  523.  
  524. #define    F_OFFSET    0x1fff    /* Offset field */
  525. #define    DF    0x4000        /* Don't fragment flag */
  526. #define    MF    0x2000        /* More Fragments flag */    
  527.  
  528.     char ttl;        /* Time to live */
  529.     char protocol;        /* Protocol */
  530.     int16 checksum;        /* Header checksum */
  531.     int32 source;        /* Source address */
  532.     int32 dest;        /* Destination address */
  533. };
  534.  
  535. /* Fields in option type byte */
  536. #define    OPT_COPIED    0x80    /* Copied-on-fragmentation flag */
  537. #define    OPT_CLASS    0x60    /* Option class */
  538. #define    OPT_NUMBER    0x1f    /* Option number */
  539.  
  540. /* IP option numbers */
  541. #define    IP_EOL        0    /* End of options list */
  542. #define    IP_NOOP        1    /* No Operation */
  543. #define    IP_SECURITY    2    /* Security parameters */
  544. #define    IP_LSROUTE    3    /* Loose Source Routing */
  545. #define    IP_TIMESTAMP    4    /* Internet Timestamp */
  546. #define    IP_RROUTE    7    /* Record Route */
  547. #define    IP_STREAMID    8    /* Stream ID */
  548. #define    IP_SSROUTE    9    /* Strict Source Routing */
  549.  
  550. /* Timestamp option flags */
  551. #define    TS_ONLY        0    /* Time stamps only */
  552. #define    TS_ADDRESS    1    /* Addresses + Time stamps */
  553. #define    TS_PRESPEC    3    /* Prespecified addresses only */
  554.  
  555. /* IP routing table entry */
  556. struct route {
  557.     struct route *prev;    /* Linked list pointers */
  558.     struct route *next;
  559.     int32 target;        /* Target IP address */
  560.     int32 gateway;        /* IP address of local gateway for this target */
  561.     int metric;        /* Hop count, whatever */
  562.     struct interface *interface;    /* Device interface structure */
  563. };
  564. #define    NULLROUTE    (struct route *)NULL
  565.  
  566. /* Reassembly descriptor */
  567. struct reasm {
  568.     struct reasm *next;    /* Linked list pointers */
  569.     struct reasm *prev;
  570.     int32 source;        /* These four fields uniquely describe a datagram */
  571.     int32 dest;
  572.     int16 id;
  573.     char protocol;
  574.     int16 length;        /* Entire datagram length, if known */
  575.     struct timer timer;    /* Reassembly timeout timer */
  576.     struct frag *fraglist;    /* Head of data fragment chain */
  577. };
  578. #define    NULLREASM    (struct reasm *)NULL
  579.  
  580. /* Fragment descriptor in a reassembly list */
  581. struct frag {
  582.     struct frag *prev;    /* Previous fragment on list */
  583.     struct frag *next;    /* Next fragment */
  584.     struct mbuf *buf;    /* Actual fragment data */
  585.     int16 offset;        /* Starting offset of fragment */
  586.     int16 last;        /* Ending offset of fragment */
  587. };
  588. #define    NULLFRAG    (struct frag *)NULL
  589.  
  590. extern struct reasm *reasmq;    /* The list of reassembly descriptors */
  591.  
  592. /* IP error logging counters */
  593. struct ip_stats {
  594.     long total;        /* Total packets received */
  595.     unsigned runt;        /* Smaller than minimum size */
  596.     unsigned length;    /* IP header length field too small */
  597.     unsigned version;    /* Wrong IP version */
  598.     unsigned checksum;    /* IP header checksum errors */
  599.     unsigned badproto;    /* Unsupported protocol */
  600. };
  601. extern struct ip_stats ip_stats;
  602. void ip_dump();
  603. SHAR_EOF
  604. cat << \SHAR_EOF > machdep.h
  605. /* This file defines certain low level operations and characteristics that
  606.  * are likely to be machine dependent.
  607.  */
  608.  
  609. #if    (MPU8086 || MPU8080 || vax)
  610. #define    LITTLE_ENDIAN    /* Low order bytes are first in memory */
  611. #endif
  612.  
  613. #ifdef    AMIGA
  614.  
  615. #ifdef    AMIGADEVDRV
  616. #define    disable()    Forbid()    /* doesn't really return a value */
  617. #define    restore(intst)    Permit()
  618.  
  619. #else
  620.  
  621. #define    disable()    (0)    /* got to return a value */
  622. #define    restore(intst)        /* but we're not gonna do anything */
  623. #endif
  624.  
  625. #ifdef WINDOWIO
  626. #ifdef    putchar
  627. #undef    putchar
  628. #endif
  629. #ifdef    fflush
  630. #undef    fflush
  631. #endif
  632. #define    putchar(c)    amigaputchar(c)
  633. #ifdef LATTICE
  634. #define    fflush(fp)    ((fp)==stdout ? amigaflush() : _flsbf(-1, fp))
  635. #else
  636. #define    fflush(fp)    ((fp)==stdout ? amigaflush() : flsh_(fp, -1))
  637. #endif
  638.                 /* this has to be the same as in stdio.h */
  639. #ifdef LATTICE
  640. #define index strchr
  641. #endif
  642. #endif
  643. #ifdef LATTICE
  644. #undef printf
  645. #endif
  646. #endif WINDOWIO
  647. /* These two lines assume that your compiler's longs are 32 bits and
  648.  * shorts are 16 bits. It is already assumed that chars are 8 bits,
  649.  * but it doesn't matter if they're signed or unsigned.
  650.  */
  651. typedef long int32;        /* 32-bit signed integer */
  652. typedef unsigned short int16;    /* 16-bit unsigned integer */
  653.  
  654. #define    bcopy(a,b,cnt)    movmem(a,b,cnt)
  655.  
  656. #ifdef    LITTLE_ENDIAN
  657. int32 ntohl();
  658. int16 ntohs();
  659. #else    /* Degenerate case for Big Endian machines */
  660. #define    ntohl(x)    (x)
  661. #define ntohs(x)    (x)
  662. #endif
  663.  
  664. #define    min(x,y)    ((x)<(y)?(x):(y))
  665. #define    max(x,y)    ((x)>(y)?(x):(y))
  666.  
  667. int16 cksum();
  668.  
  669. /* Host-to-network and network-to-host are symmetrical */
  670. #define htonl(x)    ntohl(x)
  671. #define    htons(x)    ntohs(x)
  672.  
  673. #ifdef    MPU8080    /* Assembler routines are available */
  674. int16 hinibble(),lonibble(),hibyte(),lobyte(),hiword(),loword();
  675.  
  676. #else
  677.  
  678. /* Extract a short from a long */
  679. #define    hiword(x)    ((int16)((x) >> 16))
  680. #define    loword(x)    ((int16)(x))
  681.  
  682. /* Extract a byte from a short */
  683. #define    hibyte(x)    (((x) >> 8) & 0xff)
  684. #define    lobyte(x)    ((x) & 0xff)
  685.  
  686. /* Extract nibbles from a byte */
  687. #define    hinibble(x)    (((x) >> 4) & 0xf)
  688. #define    lonibble(x)    ((x) & 0xf)
  689.  
  690. #endif
  691.  
  692. /* Define null object pointer in case stdio.h isn't included */
  693. #ifndef    NULL
  694. /* General purpose NULL pointer */
  695. #define    NULL (void *)0
  696. #endif
  697. #define    NULLCHAR (char *)NULL    /* Null character pointer */
  698. #define    NULLFP     (int (*)())0    /* Null pointer to function returning int */
  699. #define    NULLVFP     (void (*)())0    /* Null pointer to function returning void */
  700. #define    NULLFILE (FILE *)NULL    /* Null file pointer */
  701. SHAR_EOF
  702. cat << \SHAR_EOF > mbuf.h
  703. /* Basic message buffer structure */
  704. struct mbuf {
  705.     struct mbuf *next;    /* Links mbufs belonging to single packets */
  706.     struct mbuf *anext;    /* Links packets on queues */
  707.     char *data;        /* Active working pointers */
  708.     int16 cnt;
  709. };
  710. #define    NULLBUF    (struct mbuf *)NULL
  711. void enqueue(),hexdump(),asciidump();
  712. struct mbuf *alloc_mbuf(),*free_mbuf(),*dequeue(),*copy_p(),*free_p(),*qdata();
  713. int16 pullup(),append(),dup_p(),len_mbuf(),dqdata(),len_q();
  714.  
  715. SHAR_EOF
  716. cat << \SHAR_EOF > netrom.h
  717. /*
  718.  *  Define NET/ROM constants.
  719.  */
  720.  
  721. #define NETROM_SIG    0xff    /* Signature byte in NET/ROM datagrams */
  722.  
  723. struct nr {
  724.     struct interface *link;        /* pointer to companion interface */
  725.     unsigned    upd_freq;    /* routing update frequency */
  726.     char        ident[7];    /* my identifier 6 char + NUL */
  727. };
  728. SHAR_EOF
  729. cat << \SHAR_EOF > netuser.h
  730. /* Global structures and constants needed by an Internet user process */
  731. #define    NCONN    20        /* Maximum number of open network connections */
  732.  
  733. extern int32 ip_addr;    /* Our IP address */
  734.  
  735. extern int net_error;    /* Error return code */
  736. #define    NONE    0        /* No error */
  737. #define    CON_EXISTS    1    /* Connection already exists */
  738. #define    NO_CONN    2        /* Connection does not exist */
  739. #define    CON_CLOS    3    /* Connection closing */
  740. #define    NO_SPACE    4    /* No memory for TCB creation */
  741. #define    WOULDBLK    5    /* Would block */
  742. #define    NOPROTO        6    /* Protocol or mode not supported */
  743. #define    INVALID        7    /* Invalid arguments */
  744.  
  745. /* Codes for the tcp_open call */
  746. #define    TCP_PASSIVE    0
  747. #define    TCP_ACTIVE    1
  748.  
  749. /* Socket structure */
  750. struct socket {
  751.     int32 address;        /* IP address */
  752.     int16 port;            /* port number */
  753. };
  754.  
  755. /* Connection structure (two sockets) */
  756. struct connection {
  757.     struct socket local;
  758.     struct socket remote;
  759. };
  760. #define    NULLSOCK    (struct socket *)NULL
  761. int32 aton();
  762. char *inet_ntoa(),*psocket();
  763. long htol();
  764. SHAR_EOF
  765. cat << \SHAR_EOF > session.h
  766. extern int mode;
  767. #define    CMD_MODE    1    /* Command mode */
  768. #define    CONV_MODE    2    /* Converse mode */
  769.  
  770. /* Session control structure; only one entry is used at a time */
  771. struct session {
  772.     int type;
  773. #define    FREE    0
  774. #define    TELNET    1
  775. #define    FTP    2
  776.     union {
  777.         struct ftp *ftp;
  778.         struct telnet *telnet;
  779.     } cb;
  780.     int (*parse)();    /* Where to hand typed input when conversing */
  781. };
  782. #define    NULLSESSION    (struct session *)NULL
  783. extern struct session sessions[];
  784.  
  785. extern struct session *current;
  786. extern int16 lport;
  787. SHAR_EOF
  788. cat << \SHAR_EOF > slip.h
  789. /* SLIP definitions */
  790. #define    SLIP_ALLOC    40    /* Receiver allocation increment */
  791. #define    SLIP_MTU    1024    /* Maximum receiver buffer size */
  792.  
  793. #define    FR_END        0300    /* Frame End */
  794. #define    FR_ESC        0333    /* Frame Escape */
  795. #define    T_FR_END    0334    /* Transposed frame end */
  796. #define    T_FR_ESC    0335    /* Transposed frame escape */
  797.  
  798. /* Slip protocol control structure */
  799. struct slip {
  800.     struct mbuf *sndq;    /* Encapsulated packets awaiting transmission */
  801.     int16 sndcnt;        /* Number of datagrams on queue */
  802.     char escaped;        /* Receiver State control flag */
  803.     struct mbuf *rbp;    /* Head of mbuf chain being filled */
  804.     struct mbuf *rbp1;
  805.     char *rcp;        /* Write pointer */
  806.     int16 rcnt;        /* Length of mbuf chain */
  807.     struct mbuf *tbp;    /* Transmit mbuf being sent */
  808.     int16 errors;        /* Receiver input errors */
  809.     int (*recv)();        /* Function to call with an incoming buffer */
  810. };
  811. extern struct slip slip[];
  812. SHAR_EOF
  813. cat << \SHAR_EOF > smtp.h
  814. /* Turn off the next line if your system doesn't have a clock */
  815. #define    DATE
  816. /* #define USERNAME "bdale"        /* name of local user */
  817. /* #define SMTPGATE "44.32.0.1"        /* address to punt mail to */
  818. #define SMTP_PORT    25        /* well-known port for smtp */
  819. #define SMTPCLITIME    900        /* 15 minutes between client starts */
  820.  
  821. /* currently, the below definitions are set up to put incoming mail activity
  822.    in \spool\mail, and outgoing mail activity in \spool\mqueue.  Twiddle to
  823.    suit, this is for pseudo-compatibility with 4bsd, since that's what I'm
  824.    most familiar with...    Bdale  */
  825.  
  826. #ifndef    AMIGA
  827. /* Mail box file name template - edit to taste */
  828. #define    MAILSPOOL    "/spool/mail/%s.txt"
  829. /* path for outgoin mail files */
  830. #define MAILQDIR    "/spool/mqueue/"
  831. #else    AMIGA
  832. #define    MAILSPOOL    "INET:mail/%s.txt"
  833. #define    MAILQDIR    "INET:mqueue/"
  834. #endif
  835.  
  836. extern char hostname[];
  837. #define    LINELEN        128
  838. #define SLINELEN    32
  839.  
  840. /* Recipient address entry */
  841. struct addr {
  842.     struct addr *next;
  843.     char *val;
  844. };
  845. #define    NULLADDR    (struct addr *)NULL
  846.  
  847. /* Per-session control block */
  848. struct mail {
  849.     struct tcb *tcb;    /* TCP control block pointer */
  850.     char state;
  851. #define    COMMAND_STATE    0
  852. #define    DATA_STATE    1
  853.  
  854.     char *system;        /* Name of remote system */
  855.     struct addr *to;    /* Linked list of recipients */
  856.     char buf[LINELEN];    /* Input buffer */
  857.     char cnt;        /* Length of input buffer */
  858.     FILE *data;        /* Temporary input file pointer */
  859. };
  860. #define    NULLMAIL    (struct mail *)NULL
  861.  
  862. struct smtp_msg {
  863.     struct tcb *tcb;    /* tcp task control buffer */
  864.     char cts;        /* used as boolean, true if space avail in
  865.                    tcp buffer */
  866.     char state;        /* state machine placeholder */
  867. #define CLI_OPEN_STATE    0
  868. #define CLI_MAIL_STATE    1
  869. #define CLI_RCPT_STATE    2
  870. #define CLI_DATA_STATE    3
  871. #define    CLI_SEND_STATE    4
  872. #define    CLI_UNLK_STATE    5
  873. #define CLI_QUIT_STATE    6
  874.     char    *filename;    /* name of workfile */
  875.     char    toaddr[LINELEN],
  876.         fromaddr[LINELEN];
  877.     char buf[LINELEN];    /* Input buffer */
  878.     char cnt;        /* Length of input buffer */
  879.     FILE *wfile, *tfile;
  880. };
  881. SHAR_EOF
  882. cat << \SHAR_EOF > tcp.h
  883. /* TCP implementation. Follows RFC 793 as closely as possible */
  884.  
  885. #define    DEF_WND    2048    /* Default receiver window */
  886. #define    NTCB    19    /* # TCB hash table headers */
  887. #define    RETRY    10    /* Retry limit */
  888. #define    BACKOFF    1024    /* Truncation point for backoff algorithm */
  889. #define    DEF_MSS    512    /* Default maximum segment size */
  890. #define    DEF_RTT    5    /* Initial guess at round trip time (5 sec) */
  891. #define    MSL2    30    /* Guess at two maximum-segment lifetimes */
  892. /* Round trip timing parameters */
  893. #define    ALPHA1    7    /* 7/8 when delay is increasing */
  894. #define    ALPHA2    15    /* 15/16 when delay is decreasing */
  895. #define    BETA    2    /* Allow two round trip times before retransmitting */
  896. /* TCP segment header */
  897. struct tcp_header {
  898.     int16 source;    /* Source port */
  899.     int16 dest;    /* Destination port */
  900.     int32 seq;    /* Sequence number */
  901.     int32 ack;    /* Acknowledgment number */
  902.     char offset;    /* Data offset */
  903.     char flags;    /* Flags, data offset */
  904. #define    DSHIFT    4    /* Data offset field */
  905. #define    DMASK    0x0f    /* Mask for normalized data offset field */
  906. #define    URG    0x20    /* URGent flag */
  907. #define    ACK    0x10    /* ACKnowledgment flag */
  908. #define    PSH    0x08    /* PuSH flag */
  909. #define    RST    0x04    /* ReSeT flag */
  910. #define    SYN    0x02    /* SYNchronize flag */
  911. #define    FIN    0x01    /* FINal flag */
  912.     int16 wnd;    /* Receiver flow control window */
  913.     int16 checksum;    /* Header + data checksum */
  914.     int16 up;    /* Urgent pointer */
  915. };
  916.  
  917. /* Format of the Maximum Segment Size option (the only one currently
  918.  * defined in TCP)
  919.  */
  920. struct mss {
  921.     char kind;    /* Must be 2 */
  922. #define    MSS_KIND    2
  923.     char length;    /* Must be 4 */
  924. #define    MSS_LENGTH    4
  925.     int16 mss;    /* The actual value */
  926. };
  927.  
  928. /* Resequencing queue entry */
  929. struct reseq {
  930.     struct reseq *next;    /* Linked-list pointer */
  931.     char tos;        /* Type of service */
  932.     struct tcp_header seg;    /* TCP header */
  933.     struct mbuf *bp;    /* data */
  934.     int16 length;        /* data length */
  935. };
  936. #define    NULLRESEQ    (struct reseq *)NULL
  937.  
  938. /* TCP connection control block */
  939. struct tcb {
  940.     struct tcb *prev;    /* Linked list pointers for hash table */
  941.     struct tcb *next;
  942.  
  943.     struct connection conn;
  944.  
  945.     char state;    /* Connection state */
  946. #define    CLOSED        0
  947. #define    LISTEN        1
  948. #define    SYN_SENT    2
  949. #define    SYN_RECEIVED    3
  950. #define    ESTABLISHED    4
  951. #define    FINWAIT1    5
  952. #define    FINWAIT2    6
  953. #define    CLOSE_WAIT    7
  954. #define    CLOSING        8
  955. #define    LAST_ACK    9
  956. #define    TIME_WAIT    10
  957.  
  958.     char reason;        /* Reason for closing */
  959. #define    NORMAL        0    /* Normal close */
  960. #define    RESET        1    /* Reset by other end */
  961. #define    TIMEOUT        2    /* Excessive retransmissions */
  962. #define    NETWORK        3    /* Network problem (ICMP message) */
  963.  
  964. /* If reason == NETWORK, the ICMP type and code values are stored here */
  965.     char type;
  966.     char code;
  967.  
  968.     /* Send sequence variables */
  969.     struct {
  970.         int32 una;    /* First unacknowledged sequence number */
  971.         int32 nxt;    /* Next sequence num to be sent for the first time */
  972.         int32 ptr;    /* Working transmission pointer */
  973.         int16 wnd;    /* Other end's offered receive window */
  974.         int16 up;    /* Send urgent pointer */
  975.         int32 wl1;    /* Sequence number used for last window update */
  976.         int32 wl2;    /* Ack number used for last window update */
  977.     } snd;
  978.     int32 iss;        /* Initial send sequence number */
  979.  
  980.     /* Receive sequence variables */
  981.     struct {
  982.         int32 nxt;    /* Incoming sequence number expected next */
  983.         int16 wnd;    /* Our offered receive window */
  984.         int16 up;    /* Receive urgent pointer */
  985.     } rcv;
  986.     int32 irs;        /* Initial receive sequence number */
  987.     int16 mss;        /* Maximum segment size */
  988.  
  989.     char retry;        /* Retransmission retry count */
  990.     void (*r_upcall)();    /* Call when "significant" amount of data arrives */
  991.     void (*t_upcall)();    /* Call when ok to send more data */
  992.     void (*s_upcall)();    /* Call when connection state changes */
  993.     char force;        /* We owe the other end an ACK or window update */
  994.     char tos;        /* Type of service (for IP) */
  995.  
  996.     int16 window;        /* Receiver window and send queue limit */
  997.     struct mbuf *rcvq;    /* Receive queue */
  998.     int16 rcvcnt;
  999.  
  1000.     struct mbuf *sndq;    /* Send queue */
  1001.     int16 sndcnt;        /* Number of unacknowledged sequence numbers on
  1002.                  * send queue. NB: includes SYN and FIN, which don't
  1003.                  * actually appear on sndq!
  1004.                  */
  1005.     struct reseq *reseq;    /* Out-of-order segment queue */
  1006.  
  1007.     struct timer timer;    /* Retransmission timer */
  1008.     int32 rttseq;        /* Sequence number being timed */
  1009.     int32 srtt;        /* Smoothed round trip time, milliseconds */
  1010.  
  1011.     int *user;        /* User parameter (e.g., for mapping to an
  1012.                  * application control block
  1013.                  */
  1014. };
  1015. #define    NULLTCB    (struct tcb *)NULL
  1016. /* TCP statistics counters */
  1017. struct tcp_stat {
  1018.     int16 runt;        /* Smaller than minimum size */
  1019.     int16 checksum;        /* TCP header checksum errors */
  1020.     int16 conout;        /* Outgoing connection attempts */
  1021.     int16 conin;        /* Incoming connection attempts */
  1022.     int16 resets;        /* Resets generated */
  1023.     int16 bdcsts;        /* Bogus broadcast packets */
  1024. };
  1025. extern struct tcp_stat tcp_stat;
  1026. #ifndef LATTICE
  1027. #define    min(x,y)    ((x)<(y)?(x):(y))
  1028. #define max(x,y)    ((x)>(y)?(x):(y))
  1029. #endif
  1030. extern struct tcb *tcbs[];
  1031. extern int32 iss();
  1032. struct tcb *lookup_tcb();
  1033. struct tcb *create_tcb();
  1034. void rehash_tcb(),tcp_output(),tcp_input(),close_self(),dump_seg(),
  1035.     setstate();
  1036.  
  1037. /* TCP primitives */
  1038. struct tcb *open_tcp();
  1039. int send_tcp(),recv_tcp(),close_tcp(),del_tcp();
  1040. void state_tcp(),tcp_dump();
  1041.  
  1042. extern int16 tcp_mss;
  1043. extern int16 tcp_window;
  1044. SHAR_EOF
  1045. cat << \SHAR_EOF > telnet.h
  1046. #define    LINESIZE    256    /* Length of local editing buffer */
  1047. #define TELNET_PORT    23    /* TCP port for telnet service */
  1048.  
  1049. /* Telnet command characters */
  1050. #define    IAC        255    /* Interpret as command */
  1051. #define    WILL        251
  1052. #define    WONT        252
  1053. #define    DO        253
  1054. #define    DONT        254
  1055.  
  1056. /* Telnet options */
  1057. #define    TN_TRANSMIT_BINARY    0
  1058. #define    TN_ECHO            1
  1059. #define    TN_SUPPRESS_GA        3
  1060. #define    TN_STATUS        5
  1061. #define    TN_TIMING_MARK        6
  1062. #define    NOPTIONS        6
  1063.  
  1064. /* Telnet protocol control block */
  1065. struct telnet {
  1066.     struct tcb *tcb;
  1067.     char state;
  1068.  
  1069. #define    TS_DATA    0    /* Normal data state */
  1070. #define    TS_IAC    1    /* Received IAC */
  1071. #define    TS_WILL    2    /* Received IAC-WILL */
  1072. #define    TS_WONT    3    /* Received IAC-WONT */
  1073. #define    TS_DO    4    /* Received IAC-DO */
  1074. #define    TS_DONT    5    /* Received IAC-DONT */
  1075.  
  1076.     char local[NOPTIONS];    /* Local option settings */
  1077.     char remote[NOPTIONS];    /* Remote option settings */
  1078.  
  1079.     struct session *session;    /* Pointer to session structure */
  1080. };
  1081. #define    NULLTN    (struct telnet *)NULL
  1082. extern int refuse_echo;
  1083. struct telnet *open_telnet();
  1084. int send_tel(),tel_input();
  1085. SHAR_EOF
  1086. cat << \SHAR_EOF > timer.h
  1087. /* Software timers
  1088.  * There is one of these structures for each simulated timer.
  1089.  * Whenever the timer is running, it is on a doubly-linked list
  1090.  * pointed to by "timers" so that the (hardware) timer interrupt
  1091.  * can quickly run through the list and change counts and states.
  1092.  * Stopping a timer or letting it expire causes it to be removed
  1093.  * from the list; starting a timer puts it on the list.
  1094.  */
  1095. struct timer {
  1096.     struct timer *next;    /* Doubly-linked-list pointers */
  1097.     struct timer *prev;
  1098.     int16 start;        /* Period of counter (load value) */
  1099.     int16 count;        /* Ticks to go until expiration */
  1100.     void (*func)();        /* Function to call at expiration */
  1101.     int *arg;        /* Arg to pass function */
  1102.     char state;        /* Timer state */
  1103. #define    TIMER_STOP    0
  1104. #define    TIMER_RUN    1
  1105. #define    TIMER_EXPIRE    2
  1106. };
  1107. #define    NULLTIMER    (struct timer *)NULL
  1108. #define    MAX_TIME    (int16)65535    /* Max short integer */
  1109. #ifndef    MSPTICK
  1110. #define    MSPTICK        1000        /* Milliseconds per tick */
  1111. #endif
  1112. /* Useful user macros that hide the timer structure internals */
  1113. #define    set_timer(t,x)    (((t)->start) = (x)/MSPTICK)
  1114. #define    dur_timer(t)    ((t)->start)
  1115. #define    read_timer(t)    ((t)->count)
  1116. #define    run_timer(t)    (((t)->state == TIMER_RUN) ? 1 : 0)
  1117. SHAR_EOF
  1118. cat << \SHAR_EOF > trace.h
  1119. /* Dump an IP datagram header. If it's the first fragment, also dump
  1120.  * the next layer header (if known). Dumping is controlled by the low-order
  1121.  * 4 bits of the external variable "trace":
  1122.  * Level 0: no dump
  1123.  * Level 1-2: link level dumps only
  1124.  * Level 3: IP and ARP dumps only
  1125.  * Level 4: IP header + UDP or TCP header
  1126.  * Level 5: All headers + hex dump
  1127.  */
  1128. extern int32 trace;
  1129.  
  1130. #define TRACE_AX25      0x8000l
  1131. #define TRACE_EC        0x4000l
  1132. #define TRACE_PC100     0x2000l
  1133. #define TRACE_SLIP      0x1000l
  1134. #define TRACE_SDLC      0x0800l
  1135. #define TRACE_SELF    0x0400l
  1136.  
  1137. #define TRACE_HDR       0x0fl
  1138. #define TRACE_DUMP      0x10l
  1139. #define TRACE_ASCII    0x20l
  1140. #define TRACE_CMDPARSE  0x80000000l
  1141. #define TRACE_DEVICE    0x40000000l
  1142. SHAR_EOF
  1143. cat << \SHAR_EOF > udp.h
  1144. /* User Datagram Protocol definitions */
  1145.  
  1146. #define    NUDP    20
  1147.  
  1148. /* Structure of a UDP protocol header */
  1149. struct udp_header {
  1150.     int16 source;    /* Source port */
  1151.     int16 dest;    /* Destination port */
  1152.     int16 length;    /* Length of header and data */
  1153.     int16 checksum;    /* Checksum over pseudo-header, header and data */
  1154. };
  1155.  
  1156. /* User Datagram Protocol control block
  1157.  * Each entry on the receive queue consists of the
  1158.  * remote socket structure, followed by any data
  1159.  */
  1160. struct udp_cb {
  1161.     struct udp_cb *prev;    /* Linked list pointers */
  1162.     struct udp_cb *next;
  1163.     struct socket socket;    /* Local port accepting datagrams */
  1164.     void (*r_upcall)();    /* Function to call when one arrives */
  1165.     struct mbuf *rcvq;    /* Queue of pending datagrams */
  1166.     int rcvcnt;        /* Count of pending datagrams */
  1167. };
  1168. extern struct udp_cb *udps[];    /* Hash table for UDP structures */
  1169. #define    NULLUDP    (struct udp_cb *)NULL
  1170.  
  1171. /* UDP statistics counters */
  1172. struct udp_stat {
  1173.     int16 rcvd;        /* Packets received */
  1174.     int16 sent;        /* Packets sent */
  1175.     int16 cksum;        /* Checksum errors */
  1176.     int16 unknown;        /* Unknown socket */
  1177.     int16 bdcsts;        /* Incoming broadcasts */
  1178. };
  1179.  
  1180. /* UDP primitives */
  1181. int open_udp(),recv_udp(),send_udp(),del_udp();
  1182. void udp_dump();
  1183. SHAR_EOF
  1184. cat << \SHAR_EOF > cmdparse.c
  1185. /* Parse command line, set up command arguments Unix-style, and call function.
  1186.  * Note: argument is modified (delimiters are overwritten with nulls)
  1187.  * Improved error handling by Brian Boesch of Stanford University
  1188.  */
  1189. #ifdef TRACE
  1190. #include <stdio.h>
  1191. #include "machdep.h"
  1192. #include "trace.h"
  1193. #endif
  1194.  
  1195. #include "cmdparse.h"
  1196.  
  1197. int
  1198. cmdparse(cmds,line)
  1199. struct cmds cmds[];
  1200. register char *line;
  1201. {
  1202.     struct cmds *cmdp;
  1203.     char *argv[NARG],*cp,*index();
  1204.     int argc,qflag;
  1205.     int i, rslt;
  1206.  
  1207.     /* Remove cr/lf */
  1208.     if((cp = index(line,'\r')) != NULLCHAR)
  1209.         *cp = '\0';
  1210.     if((cp = index(line,'\n')) != NULLCHAR)
  1211.         *cp = '\0';    /* shouldn't be necessary */
  1212.  
  1213.     for(argc = 0;argc < NARG;argc++)
  1214.         argv[argc] = NULLCHAR;
  1215.  
  1216.     for(argc = 0;argc < NARG;){
  1217.         qflag = 0;
  1218.         /* Skip leading white space */
  1219.         while(*line == ' ' || *line == '\t')
  1220.             line++;
  1221.         if(*line == '\0')
  1222.             break;
  1223.         /* Check for quoted token */
  1224.         if(*line == '"'){
  1225.             line++;    /* Suppress quote */
  1226.             qflag = 1;
  1227.         }
  1228.         argv[argc++] = line;    /* Beginning of token */
  1229.         /* Find terminating delimiter */
  1230.         if(qflag){
  1231.             /* Find quote, it must be present */
  1232.             if((line = index(line,'"')) == NULLCHAR){
  1233.                 return -1;
  1234.             }
  1235.         } else {
  1236.             /* Find space or tab. If not present,
  1237.              * then we've already found the last
  1238.              * token.
  1239.              */
  1240.             if((cp = index(line,' ')) == NULLCHAR
  1241.              && (cp = index(line,'\t')) == NULLCHAR){
  1242.                 break;
  1243.             }
  1244.             *cp++ = '\0';
  1245.             line = cp;
  1246.         }
  1247.     }
  1248. #ifdef TRACE
  1249.     if(trace & TRACE_CMDPARSE) {
  1250.         printf("Number of tokens = %d\r\n",argc);
  1251.         for (i=0; i< argc; i++) {
  1252.             printf("Argument=%d  '%s'\r\n",i,argv[i]);
  1253.         }
  1254.     }
  1255. #endif
  1256.     if (argc < 1) {        /* empty command line */
  1257.         argc = 1;
  1258.         argv[0] = "";
  1259.     }
  1260.     /* Lines beginning with "#" are comments */
  1261.     if(argv[0][0] == '#')
  1262.         return 0;
  1263.  
  1264.     /* Look up command in table; prefix matches are OK */
  1265.     for(cmdp = cmds;cmdp->name != NULLCHAR;cmdp++){
  1266.         if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0)
  1267.             break;
  1268.     }
  1269.     if(cmdp->name == NULLCHAR) {
  1270.         if(cmdp->argc_errmsg != NULLCHAR) 
  1271.             printf("%s\r\n",cmdp->argc_errmsg);
  1272.         return -1;
  1273.     } else {
  1274.         if(argc < cmdp->argcmin) {
  1275.             /* Insufficient arguments */
  1276.             printf("Usage: %s\r\n",cmdp->argc_errmsg);
  1277.             return -1;
  1278.         } else {
  1279.             rslt = (*cmdp->func)(argc,argv);
  1280.             if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR))
  1281.                 printf("%s\r\n",cmdp->exec_errmsg);
  1282.             return(rslt);
  1283.         }
  1284.     }
  1285. }
  1286.  
  1287. /* Call a subcommand based on the first token in an already-parsed line */
  1288. int
  1289. subcmd(tab,argc,argv)
  1290. struct cmds tab[];
  1291. int argc;
  1292. char *argv[];
  1293. {
  1294.     int rslt;
  1295.     register struct cmds *cmdp;
  1296.  
  1297.     /* Strip off first token and pass rest of line to subcommand */
  1298.     if (argc < 2) {
  1299.         if (argc < 1)
  1300.             printf("SUBCMD - Don't know what to do?\r\n");
  1301.         else
  1302.             printf("\"%s\" - takes at least one argument\r\n",argv[0]);
  1303.         return -1;
  1304.     }
  1305.     argc--;
  1306.     argv++;
  1307.     for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++){
  1308.         if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0){
  1309.             if(argc < cmdp->argcmin) {
  1310.                 if (cmdp->argc_errmsg != NULLCHAR)
  1311.                     printf("Usage: %s\r\n",cmdp->argc_errmsg);
  1312.                 return -1;
  1313.             } else {
  1314.                 rslt = (*cmdp->func)(argc,argv);
  1315.                 if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR))
  1316.                     printf("%s\r\n",cmdp->exec_errmsg);
  1317.                 return(rslt);
  1318.             }
  1319.         }
  1320.     }
  1321.     if (cmdp->argc_errmsg != NULLCHAR) 
  1322.         printf("%s\r\n",cmdp->argc_errmsg);
  1323.     return -1;
  1324. }
  1325. SHAR_EOF
  1326. cat << \SHAR_EOF > ether.c
  1327. /* Stuff generic to all Ethernet controllers */
  1328. #include "machdep.h"
  1329.  
  1330. char ether_bdcst[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  1331.  
  1332. /* Format an Ethernet address into a printable ascii string */
  1333. pether(out,addr)
  1334. char *out,*addr;
  1335. {
  1336.     sprintf(out,"%02x:%02x:%02x:%02x:%02x:%02x",
  1337.         addr[0] & 0xff,
  1338.         addr[1] & 0xff,
  1339.         addr[2] & 0xff,
  1340.         addr[3] & 0xff,
  1341.         addr[4] & 0xff,
  1342.         addr[5] & 0xff,
  1343.         addr[6] & 0xff);
  1344. }
  1345.  
  1346. /* Convert an Ethernet address from Hex/ASCII to binary */
  1347. gether(out,cp)
  1348. register char *out;
  1349. register char *cp;
  1350. {
  1351.     register int i;
  1352.     char *index();
  1353.  
  1354.     for(i=6; i!=0; i--){
  1355.         *out++ = htoi(cp);
  1356.         if((cp = index(cp,':')) == NULLCHAR)    /* Find delimiter */
  1357.             break;
  1358.         cp++;            /* and skip over it */
  1359.     }
  1360. }
  1361.  
  1362.  
  1363. SHAR_EOF
  1364. cat << \SHAR_EOF > ftp.c
  1365. /* Stuff common to both the FTP server and client */
  1366. #include <stdio.h>
  1367. #include "machdep.h"
  1368. #include "mbuf.h"
  1369. #include "netuser.h"
  1370. #include "timer.h"
  1371. #include "tcp.h"
  1372. #include "ftp.h"
  1373. #include "session.h"
  1374.  
  1375. #ifdef    AMIGA
  1376. #define    UNIX    1    /* UNIX semantics work for Amiga in this module */
  1377. #endif
  1378.  
  1379. /* FTP data channel receive upcall handler */
  1380. void
  1381. r_ftpd(tcb,cnt)
  1382. struct tcb *tcb;
  1383. int16 cnt;
  1384. {
  1385.     register struct ftp *ftp;
  1386.     struct mbuf *bp;
  1387. #ifdef    UNIX
  1388.     char c;
  1389. #endif
  1390.  
  1391.     ftp = (struct ftp *)tcb->user;
  1392.     if(ftp->state != RECEIVING_STATE){
  1393.         close_tcp(tcb);
  1394.         return;
  1395.     }
  1396.     /* This will likely also generate an ACK with window rotation */
  1397.     recv_tcp(tcb,&bp,cnt);
  1398.  
  1399. #ifdef    UNIX
  1400.     while(pullup(&bp,&c,1) == 1){
  1401.         if(ftp->type == IMAGE_TYPE || c != '\r')
  1402.             putc(c,ftp->fp);
  1403.     }
  1404. #else
  1405.     while(bp != NULLBUF){
  1406.         if(bp->cnt != 0)
  1407.             fwrite(bp->data,1,(unsigned)bp->cnt,ftp->fp);
  1408.         bp = free_mbuf(bp);
  1409.     }
  1410. #endif
  1411. }
  1412. /* FTP data channel transmit upcall handler */
  1413. void
  1414. t_ftpd(tcb,cnt)
  1415. struct tcb *tcb;
  1416. int16 cnt;
  1417. {
  1418.     struct ftp *ftp;
  1419.     struct mbuf *bp;
  1420.     char *cp;
  1421.     int c;
  1422. #ifndef    CPM
  1423. #ifndef    AMIGA
  1424.     char *cdsave,*pwd();
  1425. #endif
  1426. #endif
  1427.  
  1428.     ftp = (struct ftp *)tcb->user;
  1429.     if(ftp->state != SENDING_STATE){
  1430.         close_tcp(tcb);
  1431.         return;
  1432.     }
  1433.     if((bp = alloc_mbuf(cnt)) == NULLBUF){
  1434.         /* Hard to know what to do here */
  1435.         return;
  1436.     }
  1437.     cp = bp->data;
  1438.     while(cnt > 1 && (c = getc(ftp->fp)) != EOF){
  1439. #ifdef    CPM
  1440.         if(ftp->type == ASCII_TYPE && c == CTLZ)
  1441.             break;    /* CTLZ is CP/M's text EOF marker */
  1442. #endif
  1443. #ifdef    UNIX
  1444.         if(ftp->type == ASCII_TYPE && c == '\n'){
  1445.             *cp++ = '\r';
  1446.             bp->cnt++;
  1447.             cnt--;
  1448.         }
  1449. #endif
  1450.         *cp++ = c;
  1451.         bp->cnt++;
  1452.         cnt--;
  1453.     }
  1454.     if(bp->cnt != 0)
  1455.         send_tcp(tcb,bp);
  1456.     else
  1457.         free_p(bp);
  1458.  
  1459.     if(cnt > 1){    /* EOF seen */
  1460. #ifndef    CPM
  1461. #ifndef    AMIGA
  1462.         cdsave = pwd();        /* Save current directory */
  1463.         chdir(ftp->cd);        /* Switch to user's directory*/
  1464. #endif
  1465. #endif
  1466.         fclose(ftp->fp);
  1467. #ifndef    CPM
  1468. #ifndef    AMIGA
  1469.         chdir(cdsave);        /* And back */
  1470.         free(cdsave);
  1471. #endif
  1472. #endif
  1473.         ftp->fp = NULLFILE;
  1474.         close_tcp(tcb);
  1475.     }
  1476. }
  1477. /* Allocate an FTP control block */
  1478. struct ftp *
  1479. ftp_create(bufsize)
  1480. unsigned bufsize;
  1481. {
  1482.     void ftp_delete();
  1483.     char *calloc(),*malloc();
  1484.     register struct ftp *ftp;
  1485.  
  1486.     if((ftp = (struct ftp *)calloc(1,sizeof (struct ftp))) == NULLFTP)
  1487.         return NULLFTP;
  1488.     if(bufsize != 0 && (ftp->buf = malloc(bufsize)) == NULLCHAR){
  1489.         ftp_delete(ftp);
  1490.         return NULLFTP;
  1491.     }
  1492.     ftp->state = COMMAND_STATE;
  1493.     ftp->type = ASCII_TYPE;    /* Default transfer type */
  1494.     return ftp;
  1495. }
  1496. /* Free resources, delete control block */
  1497. void
  1498. ftp_delete(ftp)
  1499. register struct ftp *ftp;
  1500. {
  1501.     if(ftp->fp != NULLFILE)
  1502.         fclose(ftp->fp);
  1503.     if(ftp->data != NULLTCB)
  1504.         del_tcp(ftp->data);
  1505.     if(ftp->username != NULLCHAR)
  1506.         free(ftp->username);
  1507.     if(ftp->buf != NULLCHAR)
  1508.         free(ftp->buf);
  1509. #ifndef    AMIGA
  1510.     if(ftp->cd != NULLCHAR)
  1511.         free(ftp->cd);
  1512. #endif
  1513.     if(ftp->session != NULLSESSION)
  1514.         ftp->session->type = FREE;
  1515.     free((char *)ftp);
  1516. }
  1517.  
  1518. #ifndef    AMIGA
  1519. /* Call getcwd(), but stick a backslash on the front (!) */
  1520. #define CWDLEN    256        /* max path len */
  1521.  
  1522. char *
  1523. pwd()
  1524. {
  1525.     char *buf,*malloc(),*getcwd();
  1526.  
  1527.     if((buf = malloc(CWDLEN+1)) == NULLCHAR)
  1528.         return NULLCHAR;
  1529.     buf[0] = '\\';
  1530.     if(getcwd(buf+1,CWDLEN) == NULLCHAR){
  1531.         free(buf);
  1532.         return NULLCHAR;
  1533.     }
  1534.     return buf;
  1535. }
  1536. #endif
  1537. SHAR_EOF
  1538. cat << \SHAR_EOF > hexload.c
  1539. /*
  1540.  *  Hex loader program.  Sends an ASCII file out the serial port to the
  1541.  *  loader running in the TNC-2 KISS loader ROM.  Use this rather than
  1542.  *  just "COPY TNC2KISS.HEX to SER:" so we don't have to depend on what
  1543.  *  the preferences baud rate for the serial port is set to.
  1544.  *
  1545.  *  Copyright (C) 1987
  1546.  *  Louis A. Mamakos
  1547.  *
  1548.  *  For non-commercial use only.  May not be sold, or included in any other
  1549.  *  product or collection of software that is sold for profit.
  1550.  */
  1551.  
  1552. #include <exec/types.h>
  1553. #include <functions.h>        /* for Manx Aztec C, get func returns */
  1554. #include <exec/nodes.h>
  1555. #include <exec/lists.h>
  1556. #include <exec/ports.h>
  1557. #include <exec/devices.h>
  1558. #include <exec/io.h>
  1559. #include <devices/serial.h>
  1560. #include <libraries/dos.h>
  1561. #include <libraries/dosextens.h>
  1562. #include <stdio.h>
  1563.  
  1564. #ifndef    DEFFILE
  1565. #define    DEFFILE    "tnc2kiss.hex"
  1566. #endif
  1567.  
  1568. #ifndef    DEFBAUD
  1569. #define    DEFBAUD    4800
  1570. #endif
  1571.  
  1572. struct IOExtSer serout;
  1573. struct MsgPort *seroutp;
  1574. struct    FileHandle    *hexfile;
  1575. char    buffer[500];
  1576. extern    int Enable_Abort;
  1577. int    baud = DEFBAUD;
  1578.  
  1579. main(argc, argv)
  1580.     int argc;
  1581.     char **argv;
  1582. {
  1583.     register long totlen = 0;
  1584.     register long len;
  1585.     
  1586.     strcpy(buffer, DEFFILE);
  1587.     if ((argc > 1) && ((baud = atoi(argv[1])) > 0)) {
  1588.         serout.io_Baud = baud;
  1589.         argc--; argv++;
  1590.         printf("Loading at %d baud\n", baud);
  1591.     }
  1592.     if (argc > 1)
  1593.         strcpy(buffer, argv[1]);
  1594.  
  1595.     hexfile = Open(buffer, MODE_OLDFILE);
  1596.  
  1597.     Enable_Abort = 0;
  1598.  
  1599.     if (hexfile == 0L) {
  1600.         printf("Can't open file '%s'\n", buffer);
  1601.         exit(1);
  1602.     }
  1603.  
  1604.     if ((seroutp = CreatePort(0L, 0L)) == NULL) {
  1605.         printf("Can't create serial input port");
  1606.         Close(hexfile);
  1607.         exit(2);
  1608.     }
  1609.     /*
  1610.      * Open serial device.
  1611.      */
  1612.     serout.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;  /* ? */
  1613.     serout.io_Status = 0;
  1614.     serout.io_Baud = baud;
  1615.     if (OpenDevice("serial.device", 0L, &serout, 0L) != 0) {
  1616.         printf("Can't open serial device");
  1617.         DeletePort(seroutp);
  1618.         Close(hexfile);
  1619.         exit(2);
  1620.     }
  1621.     serout.IOSer.io_Message.mn_ReplyPort = seroutp;
  1622.     serout.IOSer.io_Data = (APTR) buffer;
  1623.     serout.IOSer.io_Length = 0;
  1624.     serout.IOSer.io_Command = CMD_WRITE;
  1625.     serout.IOSer.io_Flags = 0;
  1626.     serout.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
  1627.     serout.io_Baud = baud;
  1628.     serout.IOSer.io_Command = SDCMD_SETPARAMS;
  1629.  
  1630.     if (DoIO(&serout))
  1631.         printf("SETPARMS failed\n");
  1632.  
  1633.     serout.IOSer.io_Command = CMD_WRITE;
  1634.     serout.IOSer.io_Data = (APTR) buffer;
  1635.     while ((len = Read(hexfile, buffer, (ULONG) sizeof(buffer))) > 0) {
  1636.         serout.IOSer.io_Length = len;
  1637.         if (DoIO(&serout))
  1638.             printf("Serial write failed %ld\n",
  1639.                 serout.IOSer.io_Error);
  1640.         totlen += len;
  1641.         if (Chk_Abort()) {
  1642.             printf("Hex load aborted!\n");
  1643.             break;
  1644.         }
  1645.     }
  1646.     printf("Wrote %ld bytes\n", totlen);
  1647.     Close(hexfile);
  1648.     CloseDevice(&serout);
  1649.     DeletePort(seroutp);
  1650. }
  1651.  
  1652. SHAR_EOF
  1653. cat << \SHAR_EOF > makefile
  1654. .c.o:
  1655.     lc -ilettuce:h -c $(CFLAGS) $<
  1656. #
  1657. #    Makefile for KA9Q TCP/IP package for PC clones with Aztec C
  1658. #
  1659. # switches:
  1660. #    define the ones you want in the CFLAGS definition...
  1661. #
  1662. #    TRACE        - turn on tracing/debugging code
  1663. #    SERVERS        - include code for application servers
  1664. #    AMIGA        - include Amiga specific code
  1665. #    MSDOS        - include Messy-Dos specific code
  1666. #    ETHER        - include ethernet specific code
  1667. #    UNIX        - Use UNIX file format conventions
  1668. #    CPM        - Use CP/M file format conventions
  1669. #    WINDOWIO    - use AMIGA windowio instead of standard IO
  1670. #
  1671. # Hardware driver flags:
  1672. #
  1673. #    SLIP        - include serial line IP stuff
  1674. #    PC_EC        - include 3Com Ethernet board driver for IBM-PC
  1675. #    AX25        - include AX.25 stuff
  1676. #    HAPN        - include HAPN stuff
  1677. #    PC100        - include PC-100 board driver (incomplete ??)
  1678. #    NETROM        - pseudo driver, needs AX.25
  1679. #    AMIGADEVDRV    - include Amiga internet.device device driver support
  1680.  
  1681. #
  1682. # CFLAGS for typical Amiga installation
  1683. #
  1684. CFLAGS= -dAMIGA -dSERVERS -dTRACE -dSLIP -dAX25 -dETHER -dMSPTICK=100 \
  1685. -dNETROM -dLATTICE -dAMIGADEVDRV -dWINDOWIO
  1686. APPLFLAGS= -dAMIGA  -dTRACE -dLATTICE -dAMIGADEVDRV 
  1687.  
  1688. NETOBJS= ftpserv.o ftpcli.o ftp.o smtpserv.o smtpcli.o \
  1689.     telnet.o tnserv.o smisc.o \
  1690.     tcpuser.o tcptimer.o tcpout.o tcpin.o tcpsubr.o udp.o \
  1691.     ip.o iproute.o icmp.o \
  1692.     ax25.o arp.o slip.o ether.o netrom.o \
  1693.     timer.o ttydriv.o cmdparse.o  mbuf.o netuser.o misc.o
  1694.  
  1695.  
  1696. net: makefile amiga.o version.o main.o devstub.o amigadev.o  $(NETOBJS)
  1697.     -blink lib:c.o version.o,main.o,amiga.o,devstub.o amigadev.o\
  1698. $(NETOBJS) to ram:net lib lib:lc.lib,lib:amiga.lib
  1699.     copy ram:net net
  1700.     delete ram:net
  1701.  
  1702. telnetp: telnetp.o netuser.o 
  1703.     -blink lib:c.o telnetp.o netuser.o to ram:telnetp \
  1704.     lib lib:lc.lib,lib:amiga.lib
  1705.     copy ram:telnetp telnetp
  1706. telnetp.o:telnetp.c machdep.h
  1707.     lc -ilettuce:h -c $(APPLFLAGS)  -dWINDOWIO telnetp.c
  1708. newtelnetp: newtelnetp.o netuser.o 
  1709.     -blink lib:c.o newtelnetp.o netuser.o to ram:newtelnetp \
  1710.     lib lib:lc.lib,lib:amiga.lib
  1711.     copy ram:newtelnetp newtelnetp
  1712.     
  1713. newtelnetp.o:newtelnetp.c machdep.h
  1714.     lc -ilettuce:h -c $(APPLFLAGS)  -dWINDOWIO newtelnetp.c
  1715. clean:    
  1716.     delete #?.o
  1717.     delete net
  1718.  
  1719. arp.o: arp.c machdep.h mbuf.h timer.h iface.h ether.h ax25.h arp.h
  1720. amiga.o: amiga.c machdep.h 
  1721. amigadev.o: amigadev.c inetdev.h machdep.h timer.h mbuf.h netuser.h internet.h ip.h tcp.h
  1722. devstub.o: devstub.asm
  1723. ax25.o: ax25.c machdep.h mbuf.h iface.h timer.h arp.h slip.h ax25.h trace.h
  1724. netrom.o: netrom.c machdep.h mbuf.h iface.h timer.h netrom.h ax25.h trace.h
  1725. cmdparse.o: cmdparse.c machdep.h trace.h cmdparse.h
  1726. ether.o: ether.c machdep.h
  1727. ftp.o: ftp.c machdep.h mbuf.h netuser.h timer.h tcp.h ftp.h session.h
  1728. ftpcli.o: ftpcli.c machdep.h mbuf.h netuser.h icmp.h timer.h tcp.h ftp.h session.h cmdparse.h
  1729. ftpserv.o: ftpserv.c machdep.h mbuf.h netuser.h timer.h tcp.h ftp.h
  1730. icmp.o: icmp.c internet.h timer.h ip.h icmp.h mbuf.h
  1731. ip.o: ip.c machdep.h mbuf.h timer.h internet.h ip.h icmp.h iface.h
  1732. iproute.o: iproute.c machdep.h mbuf.h internet.h timer.h netuser.h ip.h icmp.h iface.h trace.h
  1733. main.o: main.c machdep.h mbuf.h netuser.h timer.h icmp.h iface.h ip.h tcp.h ftp.h telnet.h session.h cmdparse.h amiga.h trace.h
  1734. mbuf.o: mbuf.c machdep.h mbuf.h
  1735. netuser.o: netuser.c machdep.h netuser.h
  1736. slip.o: slip.c machdep.h mbuf.h iface.h slip.h amiga.h trace.h
  1737. smisc.o: smisc.c machdep.h mbuf.h netuser.h timer.h tcp.h
  1738. smtpcli.o: smtpcli.c machdep.h netuser.h mbuf.h timer.h tcp.h smtp.h
  1739. smtpserv.o: smtpserv.c machdep.h mbuf.h netuser.h timer.h tcp.h smtp.h
  1740. tcpin.o: tcpin.c machdep.h timer.h mbuf.h netuser.h internet.h tcp.h icmp.h
  1741. tcpout.o: tcpout.c machdep.h timer.h mbuf.h netuser.h internet.h tcp.h
  1742. tcpsubr.o: tcpsubr.c machdep.h timer.h mbuf.h netuser.h internet.h tcp.h
  1743. tcptimer.o: tcptimer.c machdep.h timer.h mbuf.h netuser.h internet.h ip.h tcp.h
  1744. tcpuser.o: tcpuser.c machdep.h timer.h mbuf.h netuser.h internet.h ip.h tcp.h
  1745. telnet.o: telnet.c machdep.h mbuf.h timer.h internet.h icmp.h netuser.h tcp.h telnet.h session.h
  1746. tnserv.o: tnserv.c machdep.h mbuf.h timer.h internet.h icmp.h netuser.h tcp.h telnet.h session.h
  1747. timer.o: timer.c machdep.h timer.h
  1748. ttydriv.o: ttydriv.c machdep.h
  1749. udp.o: udp.c machdep.h mbuf.h netuser.h udp.h internet.h
  1750. SHAR_EOF
  1751. cat << \SHAR_EOF > misc.c
  1752. /* Miscellaneous machine independent utilities */
  1753.  
  1754. #include "machdep.h"
  1755.  
  1756. bcmp(a,b,n)
  1757. register char *a,*b;
  1758. register int16 n;
  1759. {
  1760.     while(n-- != 0){
  1761.         if(*a++ != *b++)
  1762.             return 1;
  1763.     }
  1764.     return 0;
  1765. }
  1766.  
  1767. bzero(buf,cnt)
  1768. register char *buf;
  1769. register int16 cnt;
  1770. {
  1771.     while(cnt-- != 0)
  1772.         *buf++ = '\0';
  1773. }
  1774.  
  1775. /* Convert hex-ascii to integer */
  1776. int
  1777. htoi(s)
  1778. char *s;
  1779. {
  1780.     int i = 0;
  1781.     char c;
  1782.  
  1783.     while((c = *s++) != '\0'){
  1784.         if(c == 'x')
  1785.             continue;    /* allow 0x notation */
  1786.         if('0' <= c && c <= '9')
  1787.             i = (i * 16) + (c - '0');
  1788.         else if('a' <= c && c <= 'f')
  1789.             i = (i * 16) + (c - 'a' + 10);
  1790.         else if('A' <= c && c <= 'F')
  1791.             i = (i * 16) + (c - 'A' + 10);
  1792.         else
  1793.             break;
  1794.     }
  1795.     return i;
  1796. }
  1797. SHAR_EOF
  1798. cat << \SHAR_EOF > netrom.c
  1799. /*
  1800.  * Tunnel IP datagrams thru NET/ROM nonsense.  Requires (right now) use
  1801.  * of AX.25 module.  No reason that we can't also speak their async serial
  1802.  * line protocol, expect that you'd have to have your own NET/ROM node.
  1803.  *
  1804.  * Louis A. Mamakos  WA3YMH
  1805.  */
  1806. #ifdef    NETROM
  1807. #include <stdio.h>
  1808. #include "machdep.h"
  1809. #include "mbuf.h"
  1810. #include "iface.h"
  1811. #include "ax25.h"
  1812. #include "netrom.h"
  1813.  
  1814. #ifdef    TRACE
  1815. #include "trace.h"
  1816. #endif
  1817.  
  1818. static int nnr;
  1819.  
  1820. void
  1821. netrom_input(interface, bp)
  1822.     struct interface *interface;
  1823.     struct mbuf *bp;
  1824. {
  1825.     netrom_dump(bp);    /** DEBUG **/
  1826.     free_p(bp);
  1827. }
  1828.  
  1829. #ifdef    TRACE
  1830. netrom_dump(bp)
  1831.     struct mbuf *bp;
  1832. {
  1833.     struct ax25_addr addr;
  1834.     char qual, ident[20];
  1835.  
  1836.     if (bp == NULLBUF)
  1837.         return;
  1838.  
  1839.     /* make a copy of the frame */
  1840.     if ((bp = copy_p(bp, len_mbuf(bp))) == NULL)
  1841.         return;
  1842.  
  1843.     printf("NET/ROM: ");
  1844.  
  1845.     /* first: examine the first byte in the NET/ROM packet.  If it is
  1846.      * equal to NETROM_SIG, then this frame is a routing update.
  1847.      * Otherwise, it is an inter-node frame.
  1848.      */
  1849.     if ((unsigned char) *bp->data == NETROM_SIG) {
  1850.         /* routing update */
  1851.         if (pullup(&bp, NULLCHAR, 1) != 1)    /* trash signature */
  1852.             return;
  1853.  
  1854.         /* get ident of sending node */
  1855.         ident[6] = '\0';
  1856.         if (pullup(&bp, ident, 6) != 6)
  1857.             return;
  1858.         printf("RT from %s:\r\n", ident);
  1859.         /* now, loop through and display each of the routing entries */
  1860.         for(;;) {
  1861.             if (pullup(&bp, (char *)&addr, AXALEN) != AXALEN) {
  1862.                 break;
  1863.             }
  1864.             pax25(ident, &addr);
  1865.             printf(" [%s/", ident);
  1866.             if (pullup(&bp, ident, 6) != 6) {
  1867.                 printf("\r\nMissing ident!\r\n");
  1868.                 break;
  1869.             }
  1870.             ident[6] = '\0';
  1871.             printf("%s via ", ident);
  1872.             if (pullup(&bp, (char *)&addr, AXALEN) != AXALEN) {
  1873.                 printf("Missing neighbor node\r\n");
  1874.                 break;
  1875.             }
  1876.             pax25(ident, &addr);
  1877.             if (pullup(&bp, &qual, 1) != 1) {
  1878.                 printf("missing qual\r\n");
  1879.                 break;
  1880.             }
  1881.             printf("%s qual %u]", ident, qual & 0xff);
  1882.         }
  1883.         printf("\r\n");
  1884.     } else {
  1885.         /* inter node frame */
  1886.         printf("inter-node frame\r\n");
  1887.     }    
  1888.     free_p(bp);
  1889. }
  1890. #endif    TRACE
  1891.  
  1892. /*
  1893.  *  Attach a NET/ROM virual interface to the system.  This interface needs the
  1894.  *  presence of a companion AX.25 interface to actually communicate.
  1895.  *
  1896.  *  argv[0]: hardware type: "netrom"
  1897.  *  argv[1]: name of companion ax.25 interface (like ax0)
  1898.  *  argv[2]: must be "ax25" to indicate using AX.25 as link level protocol
  1899.  *  argv[3]: label, name of interface like "nr0"
  1900.  *  argv[4]: optional: MTU
  1901.  *  argv[5]: optional: update frequency in seconds
  1902.  */
  1903. netrom_attach(argc, argv)
  1904.     int argc;
  1905.     char *argv[];
  1906. {
  1907. #ifdef    foobarbaz
  1908.     int dev;
  1909.     register struct interface *if_nr;
  1910.  
  1911.     if (nnr >= NR_MAX) {
  1912.         printf("Too many NET/ROM devices\r\n");
  1913.         return -1;
  1914.     }
  1915.  
  1916.     dev = nnr++;
  1917.     if_nr = calloc(1, sizeof(struct interface));
  1918.     
  1919. #endif    NETROM
  1920. }
  1921. #endif
  1922. SHAR_EOF
  1923. cat << \SHAR_EOF > netuser.c
  1924. /* Miscellaneous format conversion subroutines */
  1925.  
  1926. #include "machdep.h"
  1927. #include "netuser.h"
  1928. int net_error;
  1929.  
  1930. /* Convert Internet address in dotted-decimal format (44.0.0.1) to binary */
  1931. int32
  1932. aton(s)
  1933. char *s;
  1934. {
  1935.     int32 n;
  1936.     int atoi(),i;
  1937.     char *index();
  1938.  
  1939.     n = 0;
  1940.     for(i=24;i>=0;i -= 8){
  1941.         n |= (int32)atoi(s) << i;
  1942.         if((s = index(s,'.')) == NULLCHAR)
  1943.             break;
  1944.         s++;
  1945.     }
  1946.     return n;
  1947. }
  1948. /* Convert an internet address (in host byte order) to a dotted decimal ascii
  1949.  * string, e.g., 255.255.255.255\0
  1950.  */
  1951. char *
  1952. inet_ntoa(a)
  1953. int32 a;
  1954. {
  1955.     static char buf[16];
  1956.  
  1957.     sprintf(buf,"%u.%u.%u.%u",
  1958.         hibyte(hiword(a)),
  1959.         lobyte(hiword(a)),
  1960.         hibyte(loword(a)),
  1961.         lobyte(loword(a)) );
  1962.     return buf;
  1963. }
  1964. /* Convert a socket (address + port) to an ascii string of the form
  1965.  * aaa.aaa.aaa.aaa:ppppp
  1966.  */
  1967. char *
  1968. psocket(s)
  1969. struct socket *s;
  1970. {
  1971.     static char buf[30];
  1972.  
  1973.     sprintf(buf,"%s:%u",inet_ntoa(s->address),s->port);
  1974.     return buf;
  1975. }
  1976. /* Convert hex-ascii string to long integer */
  1977. long
  1978. htol(s)
  1979. char *s;
  1980. {
  1981.     long ret;
  1982.     char c;
  1983.  
  1984.     ret = 0;
  1985.     while((c = *s++) != '\0'){
  1986.         c &= 0x7f;
  1987.         if(c >= '0' && c <= '9')
  1988.             ret = ret*16 + (c - '0');
  1989.         else if(c >= 'a' && c <= 'f')
  1990.             ret = ret*16 + (10 + c - 'a');
  1991.         else if(c >= 'A' && c <= 'F')
  1992.             ret = ret*16 + (10 + c - 'A');
  1993.         else
  1994.             break;
  1995.     }
  1996.     return ret;
  1997. }
  1998. SHAR_EOF
  1999. cat << \SHAR_EOF > smisc.c
  2000. /* Miscellaneous servers */
  2001. #include <stdio.h>
  2002. #include "machdep.h"
  2003. #include "mbuf.h"
  2004. #include "netuser.h"
  2005. #include "timer.h"
  2006. #include "tcp.h"
  2007.  
  2008. static struct tcb *disc_tcb,*echo_tcb;
  2009. /* Start up discard server */
  2010. discard_start(argc,argv)
  2011. int argc;
  2012. char *argv[];
  2013. {
  2014.     struct socket lsocket;
  2015.     void r_discard(),t_state(),t_state();
  2016.  
  2017.     lsocket.address = ip_addr;
  2018.     if(argc < 2)
  2019.         lsocket.port = 9;
  2020.     else
  2021.         lsocket.port = atoi(argv[1]);
  2022.     disc_tcb = open_tcp(&lsocket,NULLSOCK,TCP_PASSIVE,0,r_discard,NULLVFP,t_state,0);
  2023. }
  2024. /* Start echo server */
  2025. echo_start(argc,argv)
  2026. int argc;
  2027. char *argv[];
  2028. {
  2029.     void r_echo(),t_echo(),t_state();
  2030.     struct socket lsocket;
  2031.  
  2032.     lsocket.address = ip_addr;
  2033.     if(argc < 2)
  2034.         lsocket.port = 7;
  2035.     else
  2036.         lsocket.port = atoi(argv[1]);
  2037.     echo_tcb = open_tcp(&lsocket,NULLSOCK,TCP_PASSIVE,0,r_echo,t_echo,t_state,0);
  2038.  
  2039. }
  2040.  
  2041. /* Shut down miscellaneous servers */
  2042. discard_stop()
  2043. {
  2044.     if(disc_tcb != NULLTCB)
  2045.         close_tcp(disc_tcb);
  2046. }
  2047. echo_stop()
  2048. {
  2049.     if(echo_tcb != NULLTCB)
  2050.         close_tcp(echo_tcb);
  2051. }
  2052.  
  2053. /* Discard server receiver upcall */
  2054. static
  2055. void
  2056. r_discard(tcb,cnt)
  2057. struct tcb *tcb;
  2058. int cnt;
  2059. {
  2060.     struct mbuf *bp;
  2061.  
  2062.     if(recv_tcp(tcb,&bp,cnt) > 0)
  2063.         free_p(bp);            /* Discard */
  2064. }
  2065.  
  2066. /* Echo server receive
  2067.  * Copies only as much will fit on the transmit queue
  2068.  */
  2069. static
  2070. void
  2071. r_echo(tcb,cnt)
  2072. struct tcb *tcb;
  2073. int cnt;
  2074. {
  2075.     struct mbuf *bp;
  2076.     int acnt;
  2077.  
  2078.     if(cnt == 0){
  2079.         close_tcp(tcb);
  2080.         return;
  2081.     }
  2082.     acnt = min(cnt,tcb->snd.wnd);
  2083.     if(acnt > 0){
  2084.         /* Get only as much will fit in the send window */
  2085.         recv_tcp(tcb,&bp,tcb->snd.wnd);
  2086.         send_tcp(tcb,bp);
  2087.     }
  2088. }
  2089. /* Echo server transmit
  2090.  * Copies anything that might have been left in the receiver queue
  2091.  */
  2092. static
  2093. void
  2094. t_echo(tcb,cnt)
  2095. struct tcb *tcb;
  2096. int cnt;
  2097. {
  2098.     struct mbuf *bp;
  2099.  
  2100.     if(tcb->rcvcnt > 0){
  2101.         /* Get only as much will fit in the send window */
  2102.         recv_tcp(tcb,&bp,cnt);
  2103.         send_tcp(tcb,bp);
  2104.     }
  2105. }
  2106.  
  2107. /* Log connection state changes; also respond to remote closes */
  2108. static
  2109. void
  2110. t_state(tcb,old,new)
  2111. register struct tcb *tcb;
  2112. char old,new;
  2113. {
  2114.     switch(new){
  2115.     case ESTABLISHED:
  2116.         log(tcb,"open %d",tcb->conn.local.port);
  2117.         break;
  2118.     case CLOSE_WAIT:
  2119.         close_tcp(tcb);
  2120.         break;
  2121.     case CLOSED:
  2122.         log(tcb,"close %d",tcb->conn.local.port);
  2123.         del_tcp(tcb);
  2124.         /* Clean up if server is being shut down */
  2125.         if(tcb == disc_tcb)
  2126.             disc_tcb = NULLTCB;
  2127.         else if(tcb == echo_tcb)
  2128.             echo_tcb = NULLTCB;
  2129.         break;
  2130.     }
  2131. }
  2132. SHAR_EOF
  2133. cat << \SHAR_EOF > tcptimer.c
  2134. /* TCP timeout routines */
  2135. #include <stdio.h>
  2136. #include "machdep.h"
  2137. #include "timer.h"
  2138. #include "mbuf.h"
  2139. #include "netuser.h"
  2140. #include "internet.h"
  2141. #include "ip.h"
  2142. #include "tcp.h"
  2143.  
  2144. /* Timer timeout */
  2145. void
  2146. tcp_timeout(arg)
  2147. int *arg;
  2148. {
  2149.     register struct tcb *tcb;
  2150.  
  2151.     tcb = (struct tcb *)arg;
  2152.     switch(tcb->state){
  2153.     case TIME_WAIT:        /* 2MSL timer has expired */
  2154.         close_self(tcb,NORMAL);
  2155.         break;
  2156.     default:        /* Retransmission timer has expired */
  2157.         if(tcb->retry < RETRY){
  2158.             tcb->retry++;
  2159.             tcb->snd.ptr = tcb->snd.una;
  2160.             /* Back off on retransmission timer;
  2161.              * on closed window probes, limit it to
  2162.              * BACKOFF x the current round trip estimate
  2163.              */
  2164.             tcb->timer.start <<= 1;
  2165.             if(tcb->snd.wnd == 0)
  2166.                 tcb->timer.start =
  2167.                  min(tcb->timer.start,BACKOFF*tcb->srtt/MSPTICK);
  2168.             tcp_output(tcb);
  2169.         } else {
  2170.             /* Give up */
  2171.             close_self(tcb,TIMEOUT);
  2172.         }
  2173.     }
  2174. }
  2175. SHAR_EOF
  2176. cat << \SHAR_EOF > timer.c
  2177. #include "machdep.h"
  2178. #include "timer.h"
  2179.  
  2180. /* Head of running timer chain */
  2181. struct timer *timers;
  2182.  
  2183. tick()
  2184. {
  2185.     register struct timer *t,*tp;
  2186.     register struct timer *expired = NULLTIMER;
  2187.  
  2188.     /* Run through the list of running timers, decrementing each one.
  2189.      * If one has expired, take it off the running list and put it
  2190.      * on a singly linked list of expired timers
  2191.      */
  2192.     for(t = timers;t != NULLTIMER; t = tp){
  2193.         tp = t->next;
  2194.         if(t->state == TIMER_RUN && --(t->count) == 0){
  2195.             stop_timer(t);
  2196.             t->state = TIMER_EXPIRE;
  2197.             /* Put on head of expired timer list */
  2198.             t->next = expired;
  2199.             expired = t;
  2200.         }
  2201.     }
  2202.     /* Now go through the list of expired timers, removing each
  2203.      * one and kicking the notify function, if there is one
  2204.      */
  2205.     while((t = expired) != NULLTIMER){
  2206.         expired = t->next;
  2207.         if(t->func){
  2208.             (*t->func)(t->arg);
  2209.         }
  2210.     }
  2211. }
  2212. /* Start a timer */
  2213. start_timer(t)
  2214. register struct timer *t;
  2215. {
  2216.     char i_state;
  2217.  
  2218.     if(t == NULLTIMER || t->start == 0)
  2219.         return;
  2220.     i_state = disable();
  2221.     t->count = t->start;
  2222.     if(t->state != TIMER_RUN){
  2223.         t->state = TIMER_RUN;
  2224.         /* Put on head of active timer list */
  2225.         t->prev = NULLTIMER;
  2226.         t->next = timers;
  2227.         if(t->next != NULLTIMER)
  2228.             t->next->prev = t;
  2229.         timers = t;
  2230.     }
  2231.     restore(i_state);
  2232. }
  2233. /* Stop a timer */
  2234. stop_timer(t)
  2235. register struct timer *t;
  2236. {
  2237.     char i_state;
  2238.  
  2239.     if(t == NULLTIMER)
  2240.         return;
  2241.     i_state = disable();
  2242.     if(t->state == TIMER_RUN){
  2243.         /* Delete from active timer list */
  2244.         if(timers == t)
  2245.             timers = t->next;
  2246.         if(t->next != NULLTIMER)
  2247.             t->next->prev = t->prev;
  2248.         if(t->prev != NULLTIMER)
  2249.             t->prev->next = t->next;
  2250.     }
  2251.     t->state = TIMER_STOP;
  2252.     restore(i_state);
  2253. }
  2254. SHAR_EOF
  2255. cat << \SHAR_EOF > tnserv.c
  2256. #include <stdio.h>
  2257. #include "machdep.h"
  2258. #include "mbuf.h"
  2259. #include "timer.h"
  2260. #include "internet.h"
  2261. #include "icmp.h"
  2262. #include "netuser.h"
  2263. #include "tcp.h"
  2264. #include "telnet.h"
  2265. #include "session.h"
  2266.  
  2267. struct tcb *tnet_tcb;
  2268. telnet_start(argc,argv)
  2269. char *argv[];
  2270. {
  2271.     struct socket lsocket;
  2272.     extern int32 ip_addr;
  2273.     void tnet_state();
  2274.     void t_state(),rcv_char();
  2275.  
  2276.     /* Incoming Telnet */
  2277.     lsocket.address = ip_addr;
  2278.     if(argc < 2)
  2279.         lsocket.port = TELNET_PORT;
  2280.     else
  2281.         lsocket.port = atoi(argv[1]);
  2282.     tnet_tcb = open_tcp(&lsocket,NULLSOCK,TCP_PASSIVE,0,rcv_char,NULLVFP,tnet_state,0,(int *)NULL);
  2283. }
  2284. /* Handle incoming Telnet connect requests by creating a Telnet session,
  2285.  * then change upcall vector so it behaves like an ordinary Telnet session.
  2286.  * 
  2287.  */
  2288. static void
  2289. tnet_state(tcb,old,new)
  2290. struct tcb *tcb;
  2291. char old,new;
  2292. {
  2293.     struct telnet *tn;
  2294.     struct session *s,*newsession();
  2295.     void t_state();
  2296.     char *calloc();
  2297.  
  2298.     switch(new){
  2299.     case ESTABLISHED:
  2300.         log(tcb,"open Telnet");
  2301.         /* Allocate a session descriptor */
  2302.         if((s = newsession()) == NULLSESSION){
  2303.             printf("\007Incoming Telnet call from %s refused; too many sessions\r\n",
  2304.              psocket(&tcb->conn.remote));
  2305.             fflush(stdout);
  2306.             sndmsg(tcb,"Call rejected; too many sessions on remote system\r\n");
  2307.             close_tcp(tcb);
  2308.             return;
  2309.         }
  2310.         s->type = TELNET;
  2311.         s->parse = send_tel;
  2312.         /* Create and initialize a Telnet protocol descriptor */
  2313.         if((tn = (struct telnet *)calloc(1,sizeof(struct telnet))) == NULLTN){
  2314.             printf("\007Incoming Telnet call refused; no space\r\n");
  2315.             fflush(stdout);
  2316.             sndmsg(tcb,"Call rejected; no space on remote system\r\n");
  2317.             close_tcp(tcb);
  2318.             s->type = FREE;
  2319.             return;
  2320.         }
  2321.         tn->session = s;    /* Upward pointer */
  2322.         tn->state = TS_DATA;
  2323.         s->cb.telnet = tn;    /* Downward pointer */
  2324.  
  2325.         tcb->user = (int *)tn;    /* Upward pointer */
  2326.         tn->tcb = tcb;        /* Downward pointer */
  2327.         printf("\007Incoming Telnet session %u from %s\r\n",s - sessions,
  2328.             psocket(&tcb->conn.remote));
  2329.         fflush(stdout);
  2330.         tcb->s_upcall = t_state;
  2331.         return;
  2332.     case CLOSED:
  2333.         /* This will only happen if the connection closed before
  2334.          * the session was set up, e.g., if we refused it because
  2335.          * there were too many sessions, or if the server is being
  2336.          * shut down.
  2337.          */
  2338.         if(tcb == tnet_tcb)
  2339.             tnet_tcb = NULLTCB;
  2340.         del_tcp(tcb);
  2341.         break;
  2342.     }
  2343. }
  2344. telnet_stop()
  2345. {
  2346.     if(tnet_tcb != NULLTCB)
  2347.         close_tcp(tnet_tcb);
  2348. }
  2349. static
  2350. sndmsg(tcb,msg)
  2351. struct tcb *tcb;
  2352. char *msg;
  2353. {
  2354.     struct mbuf *bp;
  2355.  
  2356.     bp = qdata(msg,(int16)strlen(msg));
  2357.     send_tcp(tcb,bp);
  2358. }
  2359. SHAR_EOF
  2360. cat << \SHAR_EOF > ttydriv.c
  2361. #include <stdio.h>
  2362. #include "machdep.h"
  2363.  
  2364. /* TTY input driver */
  2365. #define    NULLCHAR    (char *)NULL
  2366.  
  2367. int ttymode;
  2368. #define TTY_COOKED    0
  2369. #define    TTY_RAW    1
  2370.  
  2371. #define    LINESIZE    256
  2372.  
  2373. #ifdef    AMIGA
  2374. #define    CTLX    24
  2375. #endif
  2376.  
  2377. #define    CTLU    21
  2378.  
  2379. raw()
  2380. {
  2381.     ttymode = TTY_RAW;
  2382. }
  2383.  
  2384. cooked()
  2385. {
  2386.     ttymode = TTY_COOKED;
  2387. }
  2388.  
  2389. /* Accept characters from the incoming tty buffer and process them
  2390.  * (if in cooked mode) or just pass them directly (if in raw mode).
  2391.  * Returns the number of characters available for use; if non-zero,
  2392.  * also stashes a pointer to the character(s) in the "buf" argument.
  2393.  */
  2394. int
  2395. ttydriv(c,buf)
  2396. char c;
  2397. char **buf;
  2398. {
  2399.     static char linebuf[LINESIZE];
  2400.     static char *cp = linebuf;
  2401.     int cnt;
  2402.  
  2403.     if(buf == (char **)NULL)
  2404.         return 0;    /* paranoia check */
  2405.  
  2406.     cnt = 0;
  2407.     switch(ttymode){
  2408.     case TTY_RAW:
  2409.         *cp++ = c;
  2410.         cnt = cp - linebuf;
  2411.         cp = linebuf;
  2412.         break;
  2413.     case TTY_COOKED:
  2414.         /* Perform cooked-mode line editing */
  2415.         switch(c & 0x7f){
  2416.         case '\r':    /* CR and LF are equivalent */
  2417.         case '\n':
  2418.             *cp++ = '\r';
  2419.             *cp++ = '\n';
  2420.             printf("\r\n");
  2421.             cnt = cp - linebuf;
  2422.             cp = linebuf;
  2423.             break;
  2424.         case '\b':        /* Backspace */
  2425.             if(cp != linebuf){
  2426.                 cp--;
  2427.                 printf("\b \b");
  2428.             }
  2429.             break;
  2430.         case CTLU:    /* Line kill */
  2431. #ifdef    AMIGA
  2432.         case CTLX:
  2433. #endif
  2434.             while(cp != linebuf){
  2435.                 cp--;
  2436.                 printf("\b \b");
  2437.             }
  2438.             break;
  2439.         default:    /* Ordinary character */
  2440.             *cp++ = c;
  2441. #ifdef    AMIGA
  2442.             printf("%c", c);
  2443. #else
  2444.             putchar(c);
  2445. #endif
  2446.             if(cp >= &linebuf[LINESIZE]){
  2447.                 cnt = cp - linebuf;
  2448.                 cp = linebuf;
  2449.             }
  2450.             break;
  2451.         }
  2452.     }
  2453.     if(cnt != 0)
  2454.         *buf = linebuf;
  2455.     else
  2456.         *buf = NULLCHAR;
  2457.     fflush(stdout);
  2458.     return cnt;
  2459. }
  2460. SHAR_EOF
  2461. #    End of shell archive
  2462. exit 0
  2463. -- 
  2464. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2465. Have five nice days.
  2466.